package org.oy.sealogger.route;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

import org.apache.log4j.Logger;
import org.oy.sealogger.common.Config;
import org.oy.sealogger.logger.XMLTags;

import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;

/**
 * WaypointData represents a special spot, a waypoint, at the route. It consists of latitude and longitude and
 * can contain miscellaneous string information about the spot, a description of the place
 * or of the situation at that specific moment for instance. Additionally a bitmap image
 * can be attached.
 * @author riku
 *
 */
public class WaypointData extends GPSLocation {

	public static final String WAYPOINT_XML_START_TAG = "<Waypoint>";
	public static final String WAYPOINT_XML_END_TAG = "</Waypoint>";
	
	
	private static Logger log = Config.getLogger();
	
	private String comment = null;
	private byte[] image = null;
	
	/**
	 * Blank constructor
	 *
	 */
	public WaypointData() {}
	
	/**
	 * Constructor with pre-initialised GPSLocation.
	 * @param latitude
	 * @param longitude
	 */
	public WaypointData(double latitude, double longitude) {
		super(longitude, latitude);
	}
	
	/**
	 * Any string containing information about the waypoint
	 * @param comment
	 */
	public void setComment(String comment) {
		this.comment = comment;
	}
	
	/**
	 * Set an image related to the spot
	 * @param image Image in a raw byte array
	 */
	public void setImage(String image) {
		this.image = Base64.decode(image);
	}
	
	/**
	 * Set an image related to the spot
	 * @param image Image file handle
	 */
	public void setImage(File imgFile) {
		try {
			long size = imgFile.length();			
			
			if(size > Integer.MAX_VALUE) {
				log.error("Image too large");
				return;
			} else {
				image = new byte[(int)size];
			}
			
			FileInputStream in = new FileInputStream(imgFile);
			
			in.read(image);
			
		} catch(FileNotFoundException e) {
			log.error(e);
		} catch(IOException e) {
			log.error(e);
		}
	}
	
	/**
	 * Get comment related to the spot
	 * @return
	 */
	public String getComment() {
		return comment;
	}
	
	/**
	 * Get image related to the spot
	 * @return
	 */
	public byte[] getImage() {
		return image;
	}
	
	/**
	 * Get the spot/waypoint in an XML format
	 * @return
	 */
	public String toXMLString() {
		// TODO: XML format
		
		StringBuilder xml = new StringBuilder();
		String imageString = this.image == null ? "" : Base64.encode(image);
		String comment = this.comment == null ? "" : this.comment;
		
		xml.append("<"+XMLTags.WAYPOINT_TAG+">").append('\n');
		
		xml.append('\t').append("<"+XMLTags.LATITUDE_TAG+">").append(getLatitude()).append("</"+XMLTags.LATITUDE_TAG+">").append('\n');
		xml.append('\t').append("<"+XMLTags.LONGITUDE_TAG+">").append(getLongitude()).append("</"+XMLTags.LONGITUDE_TAG+">").append('\n');
		xml.append('\t').append("<"+XMLTags.COMMENT_TAG+">").append(comment).append("</"+XMLTags.COMMENT_TAG+">").append('\n');
		xml.append('\t').append("<"+XMLTags.IMAGE_TAG+">").append(imageString).append("</"+XMLTags.IMAGE_TAG+">").append('\n');
		
		xml.append("</"+XMLTags.WAYPOINT_TAG+">");
		
		return xml.toString();
	}
	
	public String toString() {
		return getLatitude() + ", " + getLongitude() + ", " + comment + ", " + image;
	}
}
